# --------------------------------------------构建请求URL参数-------------------------------------------------------------
"""比如
https://www.baidu.com/s?wd=iphone&rsv_spt=1
"""
"""
问号后面的部分 wd=iphone&rsv_spt=1 就是 url 参数，
每个参数之间是用 & 隔开的。
上面的例子中 有两个参数 wd 和 rsv_spt， 他们的值分别为 iphone 和 1 。
url参数的格式，术语叫 urlencoded 格式

使用Requests发送HTTP请求，url里面的参数，通常可以直接写在url里面，比如
response = requests.get('https://www.baidu.com/s?wd=iphone&rsv_spt=1')

但是有的时候，我们的url参数里面有些特殊字符，比如 参数的值就包含了 & 这个符号
那么我们可以把这些参数放到一个字典里面，然后把字典对象传递给 Requests请求方法的 params 参数，如下
urlpara = {
    'wd':'iphone&ipad',
    'rsv_spt':'1'
}

response = requests.get('https://www.baidu.com/s',params=urlpara)
"""

# --------------------------------------------构建请求消息头--------------------------------------------------------------

"""
有时候，我们需要自定义一些http的消息头
每个消息头也就是一种键值对的格式存放数据，如下所示

user-agent: my-app/0.0.1
auth-type: jwt-token
Requests发送这样的数据，只需要将这些键值对的数据填入一个字典。

然后使用post方法的时候，指定参数 headers 的值为这个字典就可以了，如下
headers = {
    'user-agent': 'my-app/0.0.1',
    'auth-type': 'jwt-token'
}
r = requests.post("http://httpbin.org/post", headers=headers)
print(r.text)
"""

# --------------------------------------------构建请求消息体--------------------------------------------------------------
"""
当我们进行API接口测试的时候， 根据接口规范，构建的http请求，通常需要构建消息体
http 的 消息体就是一串字节，里面包含了一些信息。这些信息可能是文本，比如html网页作为消息体，也可能是视频、音频等信息。
消息体可能很短 ，只有一个字节， 比如字符 a 也可能很长，有几百兆个字节，比如一个视频文件
最常见的消息体格式当然是 表示网页内容的 HTML

Web API接口中，消息体基本都是文本，文本的格式主要是这3种： urlencoded ，json ， XML
注意：消息体采用什么格式，是由 开发人员设计的决定的

1).-------------------------------XML 格式消息体
前面说了，消息体就是存放信息的地方，信息的格式完全取决设计者的需要。
如果设计者决定用 XML 格式传输一段信息，用Requests库，只需要这样
payload = '''
<?xml version="1.0" encoding="UTF-8"?>
<WorkReport>
    <Overall>良好</Overall>
    <Progress>30%</Progress>
    <Problems>暂无</Problems>
</WorkReport>
'''

r = requests.post("http://httpbin.org/post",
                  data=payload.encode('utf8'))
print(r.text)
Requests库的post方法，参数data指明了，消息体中的数据是什么。

如果传入的是字符串类型，Requests 会使用缺省编码 latin-1 编码为字节串放到http消息体中，发送出去。
而上面的例子里面包含中文，不能用缺省 latin-1编码.
所以我们将字符串对象，用 utf8 编码为字节串对象Bytes 传入给data参数，Requests就会直接把这个字符串放到 http消息体中，发送出去。
如果作为系统开发的设计者，觉得发送这样一篇报告，只需要核心信息就可以了，不需要这样麻烦的XML格式，也可以直接用纯文本，像这样
payload = '''
 report 
 Overall：良好 
 Progress: 30% 
 Problems：暂无
'''
r = requests.post("http://httpbin.org/post", 
                  data=payload.encode('utf8'))
print(r.text)
所以，如果就是一些字符信息，我们可以自行构建任何消息体格式。
但是采用 xml、json 这样的标准格式，可以很好的表示复杂的信息数据，
比如，我们要传递的工作报告里面，存在的问题有 多个，用 XML 就可以这样表示
<?xml version="1.0" encoding="UTF-8"?>
<WorkReport>
    <Overall>良好</Overall>
    <Progress>30%</Progress>
    <Problems>
       <problem  no='1'>
        <desc>问题1....</desc>
       </problem>
       <problem  no='2'>
        <desc>问题2....</desc>
       </problem>

    </Problems>
</WorkReport>
用 JSON 格式也很方便，后面会讲。
而且 编程语言都有现成的库处理解析 XML、json 这样的数据格式，我们直接拿来使用，非常方便。
而自己定义的格式就难以表达这样复制的数据格式，而且还要自己写代码在发送前进行格式转化，接收后进行格式解析，非常麻烦。

2).---------------------------------urlencoded 格式消息体
这种格式的消息体就是一种 键值对的格式存放数据，如下所示
key1=value1&key2=value2
Requests发送这样的数据，当然可以直接把这种格式的字符串传入到data参数里面。
但是，这样写的话，如果参数中本身就有特殊字符，比如等号，就会被看成参数的分隔符，就麻烦了。
我们还有更方便的方法：只需要将这些键值对的数据填入一个字典。
然后使用post方法的时候，指定参数 data 的值为这个字典就可以了，如下

payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post("http://httpbin.org/post", data=payload)
print(r.text)

3).---------------------------------json 格式消息体
json 格式 当前被 Web API 接口广泛采用。
json 是一种表示数据的语法格式。 它和Python 表示数据的语法非常像。
比如要表示上面的报告信息，可以这样
{
    "Overall":"良好",
    "Progress":"30%",
    "Problems":[
        {
            "No" : 1,
            "desc": "问题1...."
        },
        {
            "No" : 2,
            "desc": "问题2...."
        }
    ]
}
它的优点是：比xml更加简洁、清晰， 所以程序处理起来效率也更高。
我们怎样才能构建一个json格式的字符串呢？
可以使用json库的dumps方法，如下
import requests,json

payload = {
    "Overall":"良好",
    "Progress":"30%",
    "Problems":[
        {
            "No" : 1,
            "desc": "问题1...."
        },
        {
            "No" : 2,
            "desc": "问题2...."
        },
    ]
}
r = requests.post("http://httpbin.org/post", data=json.dumps(payload, ensure_ascii=False).encode())//dumps默认是ASCII编码，有中文需要手动encode
print(r.text)))                        
或者也可以将数据对象直接传递给post方法的 json参数，如下
r = requests.post("http://httpbin.org/post", json=payload)
"""